﻿using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using Microsoft.Win32;
using Xioa_UI.Convert;
using Xioa_UI.Message;

namespace Xioa_UI.Controls;

[TemplatePart(Name = "PART_PanelMain", Type = typeof(Panel))]
[TemplatePart(Name = "PART_CanvasSmallImg", Type = typeof(Canvas))]
[TemplatePart(Name = "PART_BorderMove", Type = typeof(Border))]
[TemplatePart(Name = "PART_BorderBottom", Type = typeof(Border))]
[TemplatePart(Name = "PART_ImageMain", Type = typeof(Image))]
[TemplatePart(Name = "PART_SaveButton", Type = typeof(Button))]
[TemplatePart(Name = "PART_OpenButton", Type = typeof(Button))]
[TemplatePart(Name = "PART_ReduceButton", Type = typeof(Button))]
[TemplatePart(Name = "PART_EnlargeButton", Type = typeof(Button))]
[TemplatePart(Name = "PART_RestoreButton", Type = typeof(Button))]
[TemplatePart(Name = "PART_RotateLeftButton", Type = typeof(Button))]
[TemplatePart(Name = "PART_RotateRightButton", Type = typeof(Button))]
public class XioaImageViewer : Control
{
    private const string ElementPanelMain = "PART_PanelMain";

    private const string ElementCanvasSmallImg = "PART_CanvasSmallImg";

    private const string ElementBorderMove = "PART_BorderMove";

    private const string ElementBorderBottom = "PART_BorderBottom";

    private const string ElementImageMain = "PART_ImageMain";

    private const string PART_SaveButton = "PART_SaveButton";

    private const string PART_OpenButton = "PART_OpenButton";

    private const string PART_ReduceButton = "PART_ReduceButton";

    private const string PART_EnlargeButton = "PART_EnlargeButton";

    private const string PART_RestoreButton = "PART_RestoreButton";

    private const string PART_RotateLeftButton = "PART_RotateLeftButton";

    private const string PART_RotateRightButton = "PART_RotateRightButton";

    private const double ScaleInternal = 0.2;

    private static readonly SaveFileDialog SaveFileDialog = new SaveFileDialog
    {
        Filter = "PngImg|*.png"
    };

    private Panel _panelMain;

    private Canvas _canvasSmallImg;

    private Border _borderMove;

    private Border _borderBottom;

    private Image _imageMain;

    private Button _saveButton;

    private Button _openButton;

    private Button _reduceButton;

    private Button _enlargeButton;

    private Button _restoreButton;

    private Button _rotateleftButton;

    private Button _rotaterightButton;

    private bool _borderSmallIsLoaded;

    private bool _canMoveX;

    private bool _canMoveY;

    private Thickness _imgActualMargin;

    private double _imgActualRotate;

    private double _imgActualScale = 1.0;

    private Point _imgCurrentPoint;

    private bool _imgIsMouseLeftButtonDown;

    private Thickness _imgMouseDownMargin;

    private Point _imgMouseDownPoint;

    private Point _imgSmallCurrentPoint;

    private bool _imgSmallIsMouseLeftButtonDown;

    private Thickness _imgSmallMouseDownMargin;

    private Point _imgSmallMouseDownPoint;

    private double _imgWidHeiScale;

    private bool _isOblique;

    private double _scaleInternalHeight;

    private double _scaleInternalWidth;

    private bool _showBorderBottom;

    public static readonly DependencyProperty ShowImgMapProperty =
        DependencyProperty.Register("ShowImgMap", typeof(bool), typeof(XioaImageViewer), new PropertyMetadata(false));

    public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register("ImageSource",
        typeof(BitmapFrame), typeof(XioaImageViewer), new PropertyMetadata(null, OnImageSourceChanged));

    public static readonly DependencyProperty IsFullScreenProperty =
        DependencyProperty.Register("IsFullScreen", typeof(bool), typeof(XioaImageViewer), new PropertyMetadata(false));

    internal static readonly DependencyProperty ImgPathProperty = DependencyProperty.Register("ImgPath", typeof(string),
        typeof(XioaImageViewer), new PropertyMetadata((object)null));

    internal static readonly DependencyProperty ImgSizeProperty =
        DependencyProperty.Register("ImgSize", typeof(long), typeof(XioaImageViewer), new PropertyMetadata(-1L));

    internal static readonly DependencyProperty ShowFullScreenButtonProperty =
        DependencyProperty.Register("ShowFullScreenButton", typeof(bool), typeof(XioaImageViewer),
            new PropertyMetadata(false));

    internal static readonly DependencyProperty ShowCloseButtonProperty =
        DependencyProperty.Register("ShowCloseButton", typeof(bool), typeof(XioaImageViewer), new PropertyMetadata(false));

    internal static readonly DependencyProperty ImageContentProperty = DependencyProperty.Register("ImageContent",
        typeof(object), typeof(XioaImageViewer), new PropertyMetadata((object)null));

    internal static readonly DependencyProperty ImageMarginProperty = DependencyProperty.Register("ImageMargin",
        typeof(Thickness), typeof(XioaImageViewer), new PropertyMetadata(default(Thickness)));

    internal static readonly DependencyProperty ImageWidthProperty =
        DependencyProperty.Register("ImageWidth", typeof(double), typeof(XioaImageViewer), new PropertyMetadata(0.0));

    internal static readonly DependencyProperty ImageHeightProperty =
        DependencyProperty.Register("ImageHeight", typeof(double), typeof(XioaImageViewer), new PropertyMetadata(0.0));

    internal static readonly DependencyProperty ImageScaleProperty = DependencyProperty.Register("ImageScale",
        typeof(double), typeof(XioaImageViewer), new PropertyMetadata(1.0, OnImageScaleChanged));

    internal static readonly DependencyProperty ScaleStrProperty =
        DependencyProperty.Register("ScaleStr", typeof(string), typeof(XioaImageViewer), new PropertyMetadata("100%"));

    internal static readonly DependencyProperty ImageRotateProperty =
        DependencyProperty.Register("ImageRotate", typeof(double), typeof(XioaImageViewer), new PropertyMetadata(0.0));

    internal static readonly DependencyProperty ShowSmallImgInternalProperty =
        DependencyProperty.Register("ShowSmallImgInternal", typeof(bool), typeof(XioaImageViewer),
            new PropertyMetadata(false));

    internal static readonly DependencyProperty PixelHeightProperty =
        ElementBase.Property<XioaImageViewer, int>("PixelHeightProperty", 0);
    
    internal static readonly DependencyProperty PixelWidthProperty =
        ElementBase.Property<XioaImageViewer, int>("PixelWidthProperty", 0);

    public int PixelHeight
    {
        get { return (int)GetValue(PixelHeightProperty); }
        set { SetValue(PixelHeightProperty, value); }
    }
    
    public int PixelWidth
    {
        get { return (int)GetValue(PixelWidthProperty); }
        set { SetValue(PixelWidthProperty, value); }
    }
    
    public bool IsFullScreen
    {
        get { return (bool)GetValue(IsFullScreenProperty); }
        set { SetValue(IsFullScreenProperty, value); }
    }

    public bool ShowImgMap
    {
        get { return (bool)GetValue(ShowImgMapProperty); }
        set { SetValue(ShowImgMapProperty, value); }
    }

    public BitmapFrame ImageSource
    {
        get { return (BitmapFrame)GetValue(ImageSourceProperty); }
        set { SetValue(ImageSourceProperty, value); }
    }

    internal object ImageContent
    {
        get { return GetValue(ImageContentProperty); }
        set { SetValue(ImageContentProperty, value); }
    }

    internal string? ImgPath
    {
        get { return (string)GetValue(ImgPathProperty); }
        set { SetValue(ImgPathProperty, value); }
    }

    internal long ImgSize
    {
        get { return (long)GetValue(ImgSizeProperty); }
        set { SetValue(ImgSizeProperty, value); }
    }

    internal bool ShowFullScreenButton
    {
        get { return (bool)GetValue(ShowFullScreenButtonProperty); }
        set { SetValue(ShowFullScreenButtonProperty, value); }
    }

    internal Thickness ImageMargin
    {
        get { return (Thickness)GetValue(ImageMarginProperty); }
        set { SetValue(ImageMarginProperty, value); }
    }

    internal double ImageWidth
    {
        get { return (double)GetValue(ImageWidthProperty); }
        set { SetValue(ImageWidthProperty, value); }
    }

    internal double ImageHeight
    {
        get { return (double)GetValue(ImageHeightProperty); }
        set { SetValue(ImageHeightProperty, value); }
    }

    internal double ImageScale
    {
        get { return (double)GetValue(ImageScaleProperty); }
        set { SetValue(ImageScaleProperty, value); }
    }

    internal string ScaleStr
    {
        get { return (string)GetValue(ScaleStrProperty); }
        set { SetValue(ScaleStrProperty, value); }
    }

    internal double ImageRotate
    {
        get { return (double)GetValue(ImageRotateProperty); }
        set { SetValue(ImageRotateProperty, value); }
    }

    internal bool ShowSmallImgInternal
    {
        get { return (bool)GetValue(ShowSmallImgInternalProperty); }
        set { SetValue(ShowSmallImgInternalProperty, value); }
    }

    private double ImageOriWidth { get; set; }

    private double ImageOriHeight { get; set; }

    internal bool ShowCloseButton
    {
        get { return (bool)GetValue(ShowCloseButtonProperty); }
        set { SetValue(ShowCloseButtonProperty, value); }
    }

    internal bool ShowBorderBottom
    {
        get { return _showBorderBottom; }
        set
        {
            if (_showBorderBottom != value)
            {
                _borderBottom?.BeginAnimation(UIElement.OpacityProperty,
                    value ? AnimationHelper.CreateAnimation(1.0, 100.0) : AnimationHelper.CreateAnimation(0.0, 400.0));
                _showBorderBottom = value;
            }
        }
    }

    public XioaImageViewer()
    {
        base.Loaded += delegate { Init(); };
    }

    public XioaImageViewer(Uri uri)
        : this()
    {
        try
        {
            ImageSource = BitmapFrame.Create(uri);
            ImgPath = uri.AbsolutePath;
            if (File.Exists(ImgPath))
            {
                FileInfo fileInfo = new FileInfo(ImgPath);
                ImgSize = fileInfo.Length;
            }
        }
        catch
        {
            XioaMessageBox.Show("ErrorImgPath");
        }
    }

    public XioaImageViewer(string path)
        : this(new Uri(path))
    {
    }

    private static void OnImageSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((XioaImageViewer)d).Init();
    }

    public override void OnApplyTemplate()
    {
        if (_imageMain != null)
        {
            _imageMain.MouseLeftButtonDown -= ImageMain_OnMouseLeftButtonDown;
        }

        if (_canvasSmallImg != null)
        {
            _canvasSmallImg.MouseLeftButtonDown -= CanvasSmallImg_OnMouseLeftButtonDown;
            _canvasSmallImg.MouseLeftButtonUp -= CanvasSmallImg_OnMouseLeftButtonUp;
            _canvasSmallImg.MouseMove -= CanvasSmallImg_OnMouseMove;
            _canvasSmallImg.MouseLeave -= CanvasSmallImg_OnMouseLeave;
        }

        base.OnApplyTemplate();
        _panelMain = GetTemplateChild("PART_PanelMain") as Panel;
        _canvasSmallImg = GetTemplateChild("PART_CanvasSmallImg") as Canvas;
        _borderMove = GetTemplateChild("PART_BorderMove") as Border;
        _imageMain = GetTemplateChild("PART_ImageMain") as Image;
        _borderBottom = GetTemplateChild("PART_BorderBottom") as Border;
        _saveButton = GetTemplateChild("PART_SaveButton") as Button;
        _openButton = GetTemplateChild("PART_OpenButton") as Button;
        _reduceButton = GetTemplateChild("PART_ReduceButton") as Button;
        _enlargeButton = GetTemplateChild("PART_EnlargeButton") as Button;
        _restoreButton = GetTemplateChild("PART_RestoreButton") as Button;
        _rotateleftButton = GetTemplateChild("PART_RotateLeftButton") as Button;
        _rotaterightButton = GetTemplateChild("PART_RotateRightButton") as Button;
        if (_imageMain != null)
        {
            RotateTransform rotateTransform = new RotateTransform();
            BindingOperations.SetBinding(rotateTransform, RotateTransform.AngleProperty,
                new Binding(ImageRotateProperty.Name)
                {
                    Source = this
                });
            _imageMain.LayoutTransform = rotateTransform;
            _imageMain.MouseLeftButtonDown += ImageMain_OnMouseLeftButtonDown;
        }

        if (_canvasSmallImg != null)
        {
            _canvasSmallImg.MouseLeftButtonDown += CanvasSmallImg_OnMouseLeftButtonDown;
            _canvasSmallImg.MouseLeftButtonUp += CanvasSmallImg_OnMouseLeftButtonUp;
            _canvasSmallImg.MouseMove += CanvasSmallImg_OnMouseMove;
            _canvasSmallImg.MouseLeave += CanvasSmallImg_OnMouseLeave;
        }

        _borderSmallIsLoaded = false;
        if (_saveButton != null)
        {
            _saveButton.Click += ButtonSave_OnClick;
        }

        if (_openButton != null)
        {
            _openButton.Click += ButtonWindowsOpen_OnClick;
        }

        if (_restoreButton != null)
        {
            _restoreButton.Click += ButtonActual_OnClick;
        }

        if (_reduceButton != null)
        {
            _reduceButton.Click += ButtonReduce_OnClick;
        }

        if (_enlargeButton != null)
        {
            _enlargeButton.Click += ButtonEnlarge_OnClick;
        }

        if (_rotateleftButton != null)
        {
            _rotateleftButton.Click += ButtonRotateLeft_OnClick;
        }

        if (_rotaterightButton != null)
        {
            _rotaterightButton.Click += ButtonRotateRight_OnClick;
        }
    }

    private static void OnImageScaleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        XioaImageViewer xioaImageViewer = d as XioaImageViewer;
        if (xioaImageViewer != null)
        {
            object newValue = e.NewValue;
            if (newValue is double)
            {
                double num = (double)newValue;
                xioaImageViewer.ImageWidth = xioaImageViewer.ImageOriWidth * num;
                xioaImageViewer.ImageHeight = xioaImageViewer.ImageOriHeight * num;
                DefaultInterpolatedStringHandler defaultInterpolatedStringHandler =
                    new DefaultInterpolatedStringHandler(1, 1);
                defaultInterpolatedStringHandler.AppendFormatted(num * 100.0, "#0");
                defaultInterpolatedStringHandler.AppendLiteral("%");
                xioaImageViewer.ScaleStr = defaultInterpolatedStringHandler.ToStringAndClear();
            }
        }
    }

    private void Init()
    {
        if (ImageSource == null || !base.IsLoaded)
        {
            return;
        }

        double num;
        double num2;
        if (!_isOblique)
        {
            num = ImageSource.Width;
            num2 = ImageSource.Height;
        }
        else
        {
            num = ImageSource.Height;
            num2 = ImageSource.Width;
        }

        ImageWidth = num;
        ImageHeight = num2;
        ImageOriWidth = num;
        ImageOriHeight = num2;
        _scaleInternalWidth = ImageOriWidth * 0.2;
        _scaleInternalHeight = ImageOriHeight * 0.2;
        if (Math.Abs(num2 - 0.0) < 0.001 || Math.Abs(num - 0.0) < 0.001)
        {
            XioaMessageBox.Show("ErrorImgSize");
            return;
        }

        _imgWidHeiScale = num / num2;
        double num3 = base.ActualWidth / base.ActualHeight;
        if (_imgWidHeiScale > num3)
        {
            if (num > base.ActualWidth)
            {
                ImageScale = base.ActualWidth / num;
            }
        }
        else if (num2 > base.ActualHeight)
        {
            ImageScale = base.ActualHeight / num2;
        }
        else
        {
            ImageScale = 1.0;
        }

        ImageMargin = new Thickness((base.ActualWidth - ImageWidth) / 2.0, (base.ActualHeight - ImageHeight) / 2.0, 0.0,
            0.0);
        _imgActualScale = ImageScale;
        _imgActualMargin = ImageMargin;
        InitBorderSmall();
    }

    private void ButtonActual_OnClick(object sender, RoutedEventArgs e)
    {
        DoubleAnimation doubleAnimation = AnimationHelper.CreateAnimation(1.0);
        doubleAnimation.FillBehavior = FillBehavior.Stop;
        _imgActualScale = 1.0;
        doubleAnimation.Completed += delegate
        {
            ImageScale = 1.0;
            _canMoveX = ImageWidth > base.ActualWidth;
            _canMoveY = ImageHeight > base.ActualHeight;
            BorderSmallShowSwitch();
        };
        Thickness thickness = new Thickness((base.ActualWidth - ImageOriWidth) / 2.0,
            (base.ActualHeight - ImageOriHeight) / 2.0, 0.0, 0.0);
        ThicknessAnimation thicknessAnimation = AnimationHelper.CreateAnimation(thickness);
        thicknessAnimation.FillBehavior = FillBehavior.Stop;
        _imgActualMargin = thickness;
        thicknessAnimation.Completed += delegate { ImageMargin = thickness; };
        BeginAnimation(ImageScaleProperty, doubleAnimation);
        BeginAnimation(ImageMarginProperty, thicknessAnimation);
    }

    private void ButtonReduce_OnClick(object sender, RoutedEventArgs e)
    {
        ScaleImg(isEnlarge: false);
    }

    private void ButtonEnlarge_OnClick(object sender, RoutedEventArgs e)
    {
        ScaleImg(isEnlarge: true);
    }

    private void ButtonRotateLeft_OnClick(object sender, RoutedEventArgs e)
    {
        RotateImg(_imgActualRotate - 90.0);
    }

    private void ButtonRotateRight_OnClick(object sender, RoutedEventArgs e)
    {
        RotateImg(_imgActualRotate + 90.0);
    }

    private void ButtonSave_OnClick(object sender, RoutedEventArgs e)
    {
        if (ImageSource == null)
        {
            return;
        }

        SaveFileDialog saveFileDialog = SaveFileDialog;
        DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(0, 1);
        defaultInterpolatedStringHandler.AppendFormatted(DateTime.Now, "yyyy-M-d-h-m-s.fff");
        saveFileDialog.FileName = defaultInterpolatedStringHandler.ToStringAndClear();
        if (SaveFileDialog.ShowDialog() == true)
        {
            using FileStream stream = new FileStream(SaveFileDialog.FileName, FileMode.Create, FileAccess.Write);
            PngBitmapEncoder pngBitmapEncoder = new PngBitmapEncoder();
            pngBitmapEncoder.Frames.Add(BitmapFrame.Create(ImageSource));
            pngBitmapEncoder.Save(stream);
        }
    }

    private void ButtonWindowsOpen_OnClick(object sender, RoutedEventArgs e)
    {
        try
        {
            if (ImgPath is null)
            {
                ImgPath = "C:";
                Process.Start(ImgPath);
            }
            else
            {
                Process.Start(ImgPath);
            }
           
        }
        catch (Exception ex)
        {
            XioaMessageBox.Show(ex.Message);
        }
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);
        MoveImg();
    }

    protected override void OnMouseLeave(MouseEventArgs e)
    {
        base.OnMouseLeave(e);
        _imgIsMouseLeftButtonDown = false;
        ShowBorderBottom = false;
    }

    protected override void OnMouseWheel(MouseWheelEventArgs e)
    {
        base.OnMouseWheel(e);
        ScaleImg(e.Delta > 0);
    }

    protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
    {
        base.OnRenderSizeChanged(sizeInfo);
        OnRenderSizeChanged();
    }

    private void OnRenderSizeChanged()
    {
        if (!(ImageWidth < 0.001) && !(ImageHeight < 0.001))
        {
            _canMoveX = true;
            _canMoveY = true;
            double left = ImageMargin.Left;
            double top = ImageMargin.Top;
            if (ImageWidth <= base.ActualWidth)
            {
                _canMoveX = false;
                left = (base.ActualWidth - ImageWidth) / 2.0;
            }

            if (ImageHeight <= base.ActualHeight)
            {
                _canMoveY = false;
                top = (base.ActualHeight - ImageHeight) / 2.0;
            }

            ImageMargin = new Thickness(left, top, 0.0, 0.0);
            _imgActualMargin = ImageMargin;
            BorderSmallShowSwitch();
            _imgSmallMouseDownMargin = _borderMove.Margin;
            MoveSmallImg(_imgSmallMouseDownMargin.Left, _imgSmallMouseDownMargin.Top);
        }
    }

    private void ImageMain_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        _imgMouseDownPoint = Mouse.GetPosition(_panelMain);
        _imgMouseDownMargin = ImageMargin;
        _imgIsMouseLeftButtonDown = true;
    }

    protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
    {
        base.OnPreviewMouseLeftButtonUp(e);
        _imgIsMouseLeftButtonDown = false;
    }

    private void BorderSmallShowSwitch()
    {
        if (_canMoveX || _canMoveY)
        {
            if (!_borderSmallIsLoaded)
            {
                _canvasSmallImg.Background = new VisualBrush(_imageMain);
                InitBorderSmall();
                _borderSmallIsLoaded = true;
            }

            ShowSmallImgInternal = true;
            UpdateBorderSmall();
        }
        else
        {
            ShowSmallImgInternal = false;
        }
    }

    private void InitBorderSmall()
    {
        if (_canvasSmallImg != null)
        {
            double num = _canvasSmallImg.MaxWidth / _canvasSmallImg.MaxHeight;
            if (_imgWidHeiScale > num)
            {
                _canvasSmallImg.Width = _canvasSmallImg.MaxWidth;
                _canvasSmallImg.Height = _canvasSmallImg.Width / _imgWidHeiScale;
            }
            else
            {
                _canvasSmallImg.Width = _canvasSmallImg.MaxHeight * _imgWidHeiScale;
                _canvasSmallImg.Height = _canvasSmallImg.MaxHeight;
            }
        }
    }

    private void UpdateBorderSmall()
    {
        if (ShowSmallImgInternal)
        {
            double num = Math.Min(ImageWidth, base.ActualWidth);
            double num2 = Math.Min(ImageHeight, base.ActualHeight);
            _borderMove.Width = num / ImageWidth * _canvasSmallImg.Width;
            _borderMove.Height = num2 / ImageHeight * _canvasSmallImg.Height;
            double val = (0.0 - ImageMargin.Left) / ImageWidth * _canvasSmallImg.Width;
            double val2 = (0.0 - ImageMargin.Top) / ImageHeight * _canvasSmallImg.Height;
            double val3 = _canvasSmallImg.Width - _borderMove.Width;
            double val4 = _canvasSmallImg.Height - _borderMove.Height;
            val = Math.Max(0.0, val);
            val = Math.Min(val3, val);
            val2 = Math.Max(0.0, val2);
            val2 = Math.Min(val4, val2);
            _borderMove.Margin = new Thickness(val, val2, 0.0, 0.0);
        }
    }

    private void ScaleImg(bool isEnlarge)
    {
        if (Mouse.LeftButton == MouseButtonState.Pressed)
        {
            return;
        }

        double imageWidth = ImageWidth;
        double imageHeight = ImageHeight;
        double num = (isEnlarge ? (_imgActualScale + 0.2) : (_imgActualScale - 0.2));
        if (Math.Abs(num) < 0.2 || Math.Abs(num - 50.0) < 0.001)
        {
            return;
        }

        ImageScale = num;
        Point position = Mouse.GetPosition(_panelMain);
        Point point = new Point(position.X - _imgActualMargin.Left, position.Y - _imgActualMargin.Top);
        double num2 = 0.5 * _scaleInternalWidth;
        double num3 = 0.5 * _scaleInternalHeight;
        if (ImageWidth > base.ActualWidth)
        {
            _canMoveX = true;
            if (ImageHeight > base.ActualHeight)
            {
                _canMoveY = true;
                num2 = point.X / imageWidth * _scaleInternalWidth;
                num3 = point.Y / imageHeight * _scaleInternalHeight;
            }
            else
            {
                _canMoveY = false;
            }
        }
        else
        {
            _canMoveY = ImageHeight > base.ActualHeight;
            _canMoveX = false;
        }

        Thickness thickness;
        if (isEnlarge)
        {
            thickness = new Thickness(_imgActualMargin.Left - num2, _imgActualMargin.Top - num3, 0.0, 0.0);
        }
        else
        {
            double left = _imgActualMargin.Left + num2;
            double top = _imgActualMargin.Top + num3;
            double num4 = ImageWidth - base.ActualWidth;
            double num5 = ImageHeight - base.ActualHeight;
            double num6 = Math.Abs(_borderMove.Width - _canvasSmallImg.ActualWidth + _borderMove.Margin.Left);
            double num7 = Math.Abs(_borderMove.Height - _canvasSmallImg.ActualHeight + _borderMove.Margin.Top);
            if (Math.Abs(ImageMargin.Left) < 0.001 || num6 < 0.001)
            {
                left = _imgActualMargin.Left + _borderMove.Margin.Left /
                    (_canvasSmallImg.ActualWidth - _borderMove.Width) * _scaleInternalWidth;
            }

            if (Math.Abs(ImageMargin.Top) < 0.001 || num7 < 0.001)
            {
                top = _imgActualMargin.Top + _borderMove.Margin.Top /
                    (_canvasSmallImg.ActualHeight - _borderMove.Height) * _scaleInternalHeight;
            }

            if (num4 < 0.001)
            {
                left = (base.ActualWidth - ImageWidth) / 2.0;
            }

            if (num5 < 0.001)
            {
                top = (base.ActualHeight - ImageHeight) / 2.0;
            }

            thickness = new Thickness(left, top, 0.0, 0.0);
        }

        ImageMargin = thickness;
        _imgActualScale = num;
        _imgActualMargin = thickness;
        BorderSmallShowSwitch();
        _imgSmallMouseDownMargin = _borderMove.Margin;
        MoveSmallImg(_imgSmallMouseDownMargin.Left, _imgSmallMouseDownMargin.Top);
    }

    private void RotateImg(double rotate)
    {
        _imgActualRotate = rotate;
        _isOblique = ((int)_imgActualRotate - 90) % 180 == 0;
        ShowSmallImgInternal = false;
        Init();
        InitBorderSmall();
        DoubleAnimation doubleAnimation = AnimationHelper.CreateAnimation(rotate);
        doubleAnimation.Completed += delegate { ImageRotate = rotate; };
        doubleAnimation.FillBehavior = FillBehavior.Stop;
        BeginAnimation(ImageRotateProperty, doubleAnimation);
    }

    private void MoveImg()
    {
        _imgCurrentPoint = Mouse.GetPosition(_panelMain);
        ShowCloseButton = _imgCurrentPoint.Y < 200.0;
        ShowBorderBottom = _imgCurrentPoint.Y > base.ActualHeight - 200.0;
        if (!_imgIsMouseLeftButtonDown)
        {
            return;
        }

        double num = _imgCurrentPoint.X - _imgMouseDownPoint.X;
        double num2 = _imgCurrentPoint.Y - _imgMouseDownPoint.Y;
        double num3 = _imgMouseDownMargin.Left;
        if (ImageWidth > base.ActualWidth)
        {
            num3 = _imgMouseDownMargin.Left + num;
            if (num3 >= 0.0)
            {
                num3 = 0.0;
            }
            else if (0.0 - num3 + base.ActualWidth >= ImageWidth)
            {
                num3 = base.ActualWidth - ImageWidth;
            }

            _canMoveX = true;
        }

        double num4 = _imgMouseDownMargin.Top;
        if (ImageHeight > base.ActualHeight)
        {
            num4 = _imgMouseDownMargin.Top + num2;
            if (num4 >= 0.0)
            {
                num4 = 0.0;
            }
            else if (0.0 - num4 + base.ActualHeight >= ImageHeight)
            {
                num4 = base.ActualHeight - ImageHeight;
            }

            _canMoveY = true;
        }

        ImageMargin = new Thickness(num3, num4, 0.0, 0.0);
        _imgActualMargin = ImageMargin;
        UpdateBorderSmall();
    }

    private void MoveSmallImg()
    {
        if (_imgSmallIsMouseLeftButtonDown)
        {
            _imgSmallCurrentPoint = Mouse.GetPosition(_canvasSmallImg);
            double num = _imgSmallCurrentPoint.X - _imgSmallMouseDownPoint.X;
            double num2 = _imgSmallCurrentPoint.Y - _imgSmallMouseDownPoint.Y;
            double marginX = _imgSmallMouseDownMargin.Left + num;
            double marginY = _imgSmallMouseDownMargin.Top + num2;
            MoveSmallImg(marginX, marginY);
        }
    }

    private void MoveSmallImg(double marginX, double marginY)
    {
        if (marginX < 0.0)
        {
            marginX = 0.0;
        }
        else if (marginX + _borderMove.Width >= _canvasSmallImg.Width)
        {
            marginX = _canvasSmallImg.Width - _borderMove.Width;
        }

        if (marginY < 0.0)
        {
            marginY = 0.0;
        }
        else if (marginY + _borderMove.Height >= _canvasSmallImg.Height)
        {
            marginY = _canvasSmallImg.Height - _borderMove.Height;
        }

        _borderMove.Margin = new Thickness(marginX, marginY, 0.0, 0.0);
        double left = (base.ActualWidth - ImageWidth) / 2.0;
        double top = (base.ActualHeight - ImageHeight) / 2.0;
        if (_canMoveX)
        {
            left = (0.0 - marginX) / _canvasSmallImg.Width * ImageWidth;
        }

        if (_canMoveY)
        {
            top = (0.0 - marginY) / _canvasSmallImg.Height * ImageHeight;
        }

        ImageMargin = new Thickness(left, top, 0.0, 0.0);
        _imgActualMargin = ImageMargin;
    }

    private void CanvasSmallImg_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        _imgSmallMouseDownPoint = Mouse.GetPosition(_canvasSmallImg);
        _imgSmallMouseDownMargin = _borderMove.Margin;
        _imgSmallIsMouseLeftButtonDown = true;
        e.Handled = true;
    }

    private void CanvasSmallImg_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        _imgSmallIsMouseLeftButtonDown = false;
    }

    private void CanvasSmallImg_OnMouseMove(object sender, MouseEventArgs e)
    {
        MoveSmallImg();
    }

    private void CanvasSmallImg_OnMouseLeave(object sender, MouseEventArgs e)
    {
        _imgSmallIsMouseLeftButtonDown = false;
    }
}